package com.yiji.fintech.musfinance.common.eventbus.listener;

import com.acooly.core.common.service.EntityService;
import com.acooly.core.utils.Collections3;
import com.acooly.core.utils.enums.ResultStatus;
import com.acooly.core.utils.mapper.BeanCopier;
import com.google.common.collect.Maps;
import com.google.common.eventbus.Subscribe;
import com.yiji.fintech.musfinance.base.enums.NotifyStatusEnum;
import com.yiji.fintech.musfinance.base.enums.TradeTypeEnum;
import com.yiji.fintech.musfinance.base.enums.TransStatusEnum;
import com.yiji.fintech.musfinance.center.base.result.ResultFacade;
import com.yiji.fintech.musfinance.common.annotation.ListenerAnnotation;
import com.yiji.fintech.musfinance.common.annotation.RuleStrategyAnnotation;
import com.yiji.fintech.musfinance.common.context.SpringApplicationContext;
import com.yiji.fintech.musfinance.common.domain.DepositBackDomain;
import com.yiji.fintech.musfinance.common.domain.base.BaseDomain;
import com.yiji.fintech.musfinance.common.domain.channel.ChannelDomain;
import com.yiji.fintech.musfinance.common.eventbus.event.DepositBackEvent;
import com.yiji.fintech.musfinance.common.eventbus.listener.base.AbstractCommonListener;
import com.yiji.fintech.musfinance.common.exception.AbortBizException;
import com.yiji.fintech.musfinance.common.strategy.base.AbstractRulesStrategy;
import com.yiji.fintech.musfinance.common.strategy.context.SendGeteWayContext;
import com.yiji.fintech.musfinance.common.strategy.gateway.SendGateWayDepositBackStrategy;
import com.yiji.fintech.musfinance.entity.TransactionDeopsit;
import com.yiji.fintech.musfinance.service.TransactionDeopsitService;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 充退监听器
 * Created by ouwen@yiji.com} on 2017/10/16.
 */
@ListenerAnnotation(value = "depositBackListener")
@Scope("prototype")
@Service
public class DepositBackListener extends AbstractCommonListener<DepositBackEvent,DepositBackDomain> {

    @Subscribe
    @Override
    public void doExcute(DepositBackEvent event) {
        super.doExcute(event);
    }

    /**
     * 重载路由规则
     * 备注：充退原渠道充退不需要路由规则特殊处理
     * @param domain
     */
    @Override
    public void channelRoute(DepositBackDomain domain) {
        initDoamin(domain);
        ChannelDomain channelDomain = new ChannelDomain();//Domain转换ChannelDomain
        BeanCopier.copy(domain,channelDomain,BeanCopier.CopyStrategy.IGNORE_NULL, BeanCopier.NoMatchingRule.IGNORE,null);
        //获取Domain注解上面规则策略服务
        RuleStrategyAnnotation ruleStrategyAnnotation = domain.getClass().getAnnotation(RuleStrategyAnnotation.class);
        Class strategyClass = ruleStrategyAnnotation.strategyClass();
        AbstractRulesStrategy rulesStrategy = (AbstractRulesStrategy)SpringApplicationContext.getBeanByClass(strategyClass);
        rulesStrategy.doExcute(channelDomain,domain);//执行规则策略
    }

    @Override
    protected void sendgetway(BaseDomain domain, ResultFacade result) {
        SendGateWayDepositBackStrategy depositBackStrategy = (SendGateWayDepositBackStrategy) SpringApplicationContext.getBeanByClass(SendGateWayDepositBackStrategy.class);
        SendGeteWayContext context = new SendGeteWayContext(depositBackStrategy);
        context.doSendGateWay(domain,result);
    }

    @Override
    protected void initTransaction(BaseDomain domain) {
        DepositBackDomain depositBackDomain = (DepositBackDomain)domain;
        depositBackDomain.setStatus(ResultStatus.processing);
        depositBackDomain.setNotifyStatus(NotifyStatusEnum.NO);
        depositBackDomain.setGatewayTime(new Date());
        depositBackDomain.setTransStatus(TransStatusEnum.BANK_PROCESSING);
    }

    /**
     * 初始化Domain信息
     * @param domain
     */
    private void initDoamin(DepositBackDomain domain){
        //充值服务
        EntityService depositService = getDbService(TransactionDeopsitService.class);
        //查询原订单
        Map<String,Object> params = Maps.newHashMap();
        params.put("EQ_bizOrderNo",domain.getOldBizOrderNo());
        params.put("EQ_merchOrderNo",domain.getOldMerchOrderNo());
        List datas = depositService.query(params,null);
        if(Collections3.isNotEmpty(datas)){
            TransactionDeopsit transactionDeopsit = (TransactionDeopsit) datas.get(0);
            if(TransStatusEnum.BANK_SUCCESS != transactionDeopsit.getTransStatus()){
                throw new AbortBizException("原交易订单状态【"+transactionDeopsit.getTransStatus()+"】");
            }
            domain.setBackAccountName(transactionDeopsit.getPayAccountName());
            domain.setBackAccountNo(transactionDeopsit.getPayAccountNo());
            domain.setBackBankId(transactionDeopsit.getPayBankId());
            domain.setOldTradeType(transactionDeopsit.getTradeType());
            domain.setTradeType(TradeTypeEnum.DEPOSIT_BACK);
            domain.setGatewayChannelApi(transactionDeopsit.getGatewayChannelApi());
            domain.setOldGatewayChannelApi(transactionDeopsit.getGatewayChannelApi());
        }
    }
}
